/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package nsip.model;

import nsip.transport.NsipTransport;

/**
 *
 * @author nico.rehwaldt
 */
public final class Item extends DataRecord implements SchedulableEntity {
    
    private Item parent;
    private Metadata metadata = new Metadata();
    
    public Item(DataRecord record) {
        update(record);
    }

    /**
     * @return the id
     */
    public int getId() {
        return id;
    }

    /**
     * @return the type
     */
    public ItemType getType() {
        return type;
    }

    /**
     * @return the productID
     */
    public int getProductID() {
        return productID;
    }

    /**
     * @return the peerAddress
     */
    public String getPeerAddress() {
        return peerAddress;
    }

    /**
     * @return the status
     */
    public ItemStatus getStatus() {
        return status;
    }

    /**
     * @return the dueDate
     */
    public int getDueDate() {
        return dueDate;
    }

    /**
     * @return the quantity
     */
    public int getQuantity() {
        return quantity;
    }

    /**
     * @return the penalty
     */
    public int getPenalty() {
        return penalty;
    }

    /**
     * @return the pricePerUnit
     */
    public int getPricePerUnit() {
        return pricePerUnit;
    }

    @Override
    public String toString() {
        return 
            getType() + "#" + getStatus() +
            "[" + getId() + "," + getProductID() + "," + getQuantity() + "," + getPricePerUnit() + "," + getDueDate() + "]";
    }

    /**
     * Returns some valuable metadata for this object
     * @return
     */
    public Metadata metadata() {
        return metadata;
    }

    /**
     * Copies this item and returns the result.
     * Will typically set the copies id to zero.
     *
     * @return
     */
    public Item copy() {
        Item copy = new Item(this);
        copy.parent = this;
        copy.metadata = this.metadata;
        copy.id = -1;
        
        return copy;
    }

    /**
     * Update the item with the given data record and return it.
     * 
     * @param record
     * @return the record
     */
    public Item update(DataRecord record) {
        record.update(this);
        return this;
    }

    /**
     * Return true if the of this item is equal to the argument
     * @param status
     * @return
     */
    public boolean hasStatus(ItemStatus status) {
        return (this.status == status);
    }

    /**
     * Check if an id is set on the specified item. If not, set it using
     * an id generated from the specified id generator.
     * 
     * @param model
     * @param idGenerator
     */
    public static void checkSetID(Item model, NsipTransport idGenerator) {
        if (model.id == -1) {
            model.id = idGenerator.generateID();
        }
    }

    /**
     * Updates the status of this item
     * @param status
     */
    public void setStatus(ItemStatus status) {
        this.status = status;
    }

    /**
     * Returns the parent of this item (in case it has one) or null if none
     * is present
     * 
     * @return
     */
    public Item getParent() {
        return parent;
    }

    /**
     * {@inheritDoc}
     */
    public int getProductionDueDate() {
        // TODO: Check if this is correct
        return dueDate - 1;
    }

    /**
     * {@inheritDoc}
     */
    public int getProductionCyclesNeeded() {
        return metadata().getInfo().getRequiredAssemblyCycles() * quantity;
    }

    /**
     * {@inheritDoc}
     */
    public boolean isGap() {
        return false;
    }

    /**
     * {@inheritDoc}
     */
    public boolean isOrder() {
        return type == ItemType.ORDER;
    }

    public boolean isRfq() {
        return type == ItemType.RFQ;
    }

    /**
     * Return the penalty per unit
     * @return
     */
    public double getPenaltyPerUnit() {
        return ((double) penalty) / quantity;
    }

    @Override
    public int hashCode() {
        if (id != -1) {
            return id;
        } else {
            return super.hashCode();
        }
    }

    @Override
    public boolean equals(Object obj) {
        return (obj instanceof Item && obj.hashCode() == hashCode());
    }
}
